package ext.tianma.bom.service.rdpInterface;

import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.remoting.support.RemoteAccessor;
import org.springframework.stereotype.Service;

import wt.doc.WTDocument;
import wt.fc.ObjectReference;
import wt.fc.QueryResult;
import wt.fc.collections.WTArrayList;
import wt.part.WTPart;
import wt.part.WTPartHelper;
import wt.part.WTPartMaster;
import wt.part.WTPartSubstituteLink;
import wt.part.WTPartUsageLink;
import wt.type.TypedUtility;
import wt.util.WTException;
import wt.util.WTProperties;
import wt.vc.Iterated;
import wt.vc.config.ConfigHelper;
import wt.vc.config.ConfigSpec;
import wt.vc.config.LatestConfigSpec;
import ext.com.core.CoreUtil;
import ext.tianma.bom.eco.BOMHelp;
import ext.tianma.number.util.PartUtil;
import ext.tianma.util.TMUtil;

/**
 * 类名: RDPServcie </br>
 * 包名: ext.tianma.integration
 * 描述: PLM提供接口，供RDP调用
 * @author xucr
 * 创建时间: 2020年10月19日
 * 发布版本: V1.0
 */

@Service
public class RDPService extends RemoteAccessor {

	private static final Logger logger = LoggerFactory.getLogger(RDPService.class);
	private static final String SEMIFINISHEDGOOD = "cn.tianma.SemiFinishedGood"; // 半成品
	private static final String PROCESSDOCUMENTS = "cn.tianma.ProcessDocuments";//工艺文件
	private static final String CONTROLDOCUMENT = "cn.tianma.ControlDocument";//受控PDF图纸
	public static final String MSG = "msg";
	public static final String CODE = "code";
	public static final String SUCCESS = "success";
	public static final String CODE_SUCCESS = "200";
	public static final String CODE_FAILED = "0";
	public static final String DATA = "data";
	/**
	 * 获取BOM接口、受控文件、工艺文件
	 * @return
	 * @author xucr
	 * @CreateDate 2020年10月12日
	 */
	public JSONObject getBOMFile(JSONObject paramObject) {
		JSONObject obj = null;
		String [] paramKeys = {"productNumber", "view"};
		Map<String, String> resutlMap = new HashMap<String, String>();
		try {
			obj = checkParams(paramObject, paramKeys, resutlMap);
			if(obj == null || obj.length() == 0) { //满足条件
//				WTPart wtpart = CommonPDMUtil.getWTPartByNumViewAndVersion(
//						resutlMap.get("productNumber"), resutlMap.get("view"), resutlMap.get("version"));
				WTPart wtpart = CoreUtil.getWTPartByNumberAndView(resutlMap.get("productNumber"), resutlMap.get("view"));// 获取design试图
				Map<WTPart, WTPart> map = new HashMap<WTPart, WTPart>();
				Map<String, String> map2 = new HashMap<String, String>();
				getChildPart(wtpart, map, map2);
				
				//获取受控文件、工艺文件：仅发布的
				if(map.size() > 0) {
					JSONObject dataObject = null;
					JSONArray dataArray = new JSONArray();
					
					WTPart part = null;
					JSONArray attachments = null;
					for (Entry<WTPart, WTPart> set : map.entrySet()) {
						part = set.getKey();
						
						attachments = getWTPartFile(part);
						
						dataObject = new JSONObject();
						dataObject.put("id", TMUtil.obj2Oid(part));
						dataObject.put("productNumber", part.getNumber());
						dataObject.put("name", part.getName());
						dataObject.put("parentId", set.getValue()); //父项id
						dataObject.put("attachments", attachments);
						dataArray.put(dataObject);
					}
					obj = respInfo(dataArray, "");
				} else {
					obj = respInfo(null, "料号【"+resutlMap.get("productNumber")+"】暂无BOM结构");
				}
			}
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		}
		return obj;
	}
	
	/**
	 * 获取BOM下的半成品
	 * @param paramObject
	 * @return
	 * @author xucr
	 * @CreateDate 2020年10月19日
	 */
	public JSONObject getSemiFinishedGoodByBOM(JSONObject paramObject) {
		String [] paramKeys = {"productNumber", "view"};
		Map<String, String> resutlMap = new HashMap<String, String>();
		JSONObject obj = null;
		try {
			obj = checkParams(paramObject, paramKeys, resutlMap);
			if(obj == null || obj.length() == 0) { //满足条件
				obj = getBOMToSemiFinishedGood(resutlMap.get("productNumber"), resutlMap.get("view"));
			}
		} catch (JSONException e1) {
			e1.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		}
		return obj;
	}
	
	/**
	 * 校验接口参数
	 * @param paramObject
	 * @param paramKeys
	 * @param resutlMap
	 * @return
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年10月19日
	 */
	private JSONObject checkParams(JSONObject paramObject, String [] paramKeys, Map<String, String> resutlMap) throws JSONException {
		/**
		 * 校验接口所需参数，当所有参数均满足后，返回所有参数值
		 * */
		String tip = "查询失败，缺少参数：";
		boolean isTip = false;
		JSONObject obj = null;
		for(int i = 0 ; i < paramKeys.length; i++) {
			String key = paramKeys[i];
			if(paramObject.has(key)){
				resutlMap.put(key, paramObject.getString(key));
			} else {
				isTip = true;
				tip += key + "、";
			}
		}
		if(isTip) {
			obj = respInfo(null, tip);
		} else {
			obj = new JSONObject();
		}
		return obj;
	}
	
	/**
	 * 返回值
	 * @param array 数据
	 * @param msg 提示
	 * @return
	 * @throws JSONException
	 * @author xucr
	 * @CreateDate 2020年10月13日
	 */
	private JSONObject respInfo(JSONArray array, String msg) throws JSONException {
		JSONObject result = new JSONObject();
		if(null != array && array.length() > 0) {
			result.put(MSG, "");
			result.put(SUCCESS, true);
			result.put(CODE, CODE_SUCCESS);
			result.put(DATA, array);
		} else {
			result.put(MSG, msg);
			result.put(SUCCESS, false);
			result.put(CODE, CODE_FAILED);
		}
		return result;
	}

	/**
	 * 根据顶层BOM获取所有的子项
	 * 
	 * @param part    顶层
	 * @param allhash 返回结果集
	 * @throws WTException
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void getChildAllPart(WTPart part, Hashtable allhash) throws WTException {
		// 得到第一层子项
		Vector v = getFirstChildPart(part);
		for (int i = 0; i < v.size(); i++) {
			WTPart subPart = (WTPart) v.elementAt(i);

			// 判断子项是否是"cn.tianma.SemiFinishedGood",防止BOM下面有成品，成品下面有半成品查询不到
			String typeName = TypedUtility.getTypeIdentifier(subPart).getTypename();
			if (typeName.contains(SEMIFINISHEDGOOD)) {
				allhash.put(subPart.getNumber(), subPart);
			}

			// 判断子项是否存在替代料
			WTArrayList c = (WTArrayList) WTPartHelper.service
					.getSubstituteLinksAnyAssembly((WTPartMaster) subPart.getMasterReference().getObject());
			for (int j = 0; j < c.size(); j++) {
				// 得到WTPartSubstituteLink 表，查看关系
				WTPartSubstituteLink s = (WTPartSubstituteLink) ((ObjectReference) c.get(j)).getObject();

				// 得到wtpartmaster对象并转换为wtpart对象
				WTPartMaster partSubMaster = (WTPartMaster) s.getRoleBObject();
				WTPart partSub = getLatestPartByPartMaster(partSubMaster);
				String type = TypedUtility.getTypeIdentifier(partSub).getTypename();
				if (type.contains(SEMIFINISHEDGOOD)) {
					allhash.put(partSub.getNumber(), partSub);
				}
			}

			// 递归
			getChildAllPart(subPart, allhash);
		}
	}

	/**
	 * 得到部件的直接子项
	 *
	 * @param part
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private Vector getFirstChildPart(WTPart part) {
		Vector result = new Vector();
		try {
			QueryResult qr = WTPartHelper.service.getUsesWTPartMasters(part);
			while (qr.hasMoreElements()) {
				WTPartUsageLink link = (WTPartUsageLink) qr.nextElement();
//				WTPartMaster master = (WTPartMaster) link.getAllObjects()[1];
				WTPartMaster master = (WTPartMaster) link.getRoleBObject();// modify by xucr
				WTPart partlist = getLatestPartByPartMaster(master);
				result.addElement(partlist);
			}
		} catch (WTException e) {
			e.printStackTrace();
		}
		return result;
	}

	// 通过WTPartMaster 返回最新版本WTPart对象
	private WTPart getLatestPartByPartMaster(WTPartMaster paramWTPartMaster) throws WTException {
		Iterated localIterated = null;
		boolean bool = false;
		LatestConfigSpec localLatestConfigSpec = new LatestConfigSpec();
		QueryResult localQueryResult = ConfigHelper.service.filteredIterationsOf(paramWTPartMaster,
				localLatestConfigSpec);
		if ((localQueryResult != null) && (localQueryResult.size() <= 0)) {
			ConfigSpec localConfigSpec = ConfigHelper.service.getDefaultConfigSpecFor(WTPartMaster.class);
			localQueryResult = ConfigHelper.service.filteredIterationsOf(paramWTPartMaster, localConfigSpec);
		}
		while ((localQueryResult.hasMoreElements()) && (!bool)) {
			localIterated = (Iterated) localQueryResult.nextElement();
			bool = localIterated.isLatestIteration();
		}
		return (WTPart) localIterated;
	}

	/**
	 * 根据BOM获取指定类型的子项，同时封装数据
	 * 
	 * @param productNumber BOM编号 view BOM视图
	 * @throws WTException
	 * @throws JSONException
	 * @throws RemoteException
	 */
	@SuppressWarnings("rawtypes")
	private  JSONObject getBOMToSemiFinishedGood(String productNumber, String view)
			throws WTException, JSONException, RemoteException {
		JSONObject result = new JSONObject();
		logger.info("BOM编号：" + productNumber + ",视图为：" + view);
		// 根据编号、视图、版本号拿到BOM
//		WTPart part = CommonPDMUtil.getWTPartByNumViewAndVersion(productNumber, view, version);
		WTPart part = CoreUtil.getWTPartByNumberAndView(productNumber, view);// 获取design试图
		if(part == null) {
			return result;
		}
		Hashtable allHash = new Hashtable();
		getChildAllPart(part, allHash);

		if (null != allHash && allHash.size() > 0) {

			JSONArray data = new JSONArray();
			Enumeration e = allHash.keys();
			JSONObject data1 = null;
			String key = "";
			WTPart p = null;
			while (e.hasMoreElements()) {
				data1 = new JSONObject();
				key = (String) e.nextElement();
				p = (WTPart) allHash.get(key);

				data1.put("id", p.getPersistInfo().getObjectIdentifier().getId());
				data1.put("productNumber", p.getNumber());
				data1.put("name", p.getName());
				data1.put("view", p.getViewName());
				data.put(data1);
			}

			result.put("data:", data);
			result.put("code", CODE_SUCCESS);
			result.put("success", true);
		} else {
			result.put("data", "未查询到BOM下的半成品！！！");
			result.put("code", CODE_FAILED);
			result.put("success", false);
		}
		return result;
	}
	
	
	
	/**------------------------------------------------------------------------------------------------------*/
	
	
	/**
	 * 递归获取BOM结构，含特定替换部件
	 * @param part
	 * @param map
	 * @author xucr
	 * @CreateDate 2020年10月13日
	 */
	private  void getChildPart(WTPart part, Map<WTPart, WTPart> map, Map<String,String> map2) {
		try {
			QueryResult qs = WTPartHelper.service.getUsesWTPartMasters(part);
			while (qs.hasMoreElements()) {
				WTPartUsageLink link = (WTPartUsageLink) qs.nextElement();
				WTPartMaster master = (WTPartMaster) link.getRoleBObject();
				/**
				 * WTPart childpart = BOMHelp.getPart(master.getNumber(), "", part.getViewName());
				 * 理论上，
				 * 物料转厂的时候，会将子项视图设定为一至，
				 * 但有特例，会单独添加料号，但无法控制视图，因此我们这里不能按照视图一样来查询
				 */
				WTPart childpart = PartUtil.getWTPartByNumber(master.getNumber());
				
				if (!map.containsKey(childpart)) {
					//特定替换部件
					WTArrayList c = (WTArrayList)WTPartHelper.service.getSubstituteLinksAnyAssembly(
							(WTPartMaster) childpart.getMasterReference().getObject());
					if(null != c && c.size() > 0) {
						ObjectReference obj = null;
						for(int j = 0 ; j < c.size(); j++) {
							obj =  (ObjectReference) c.get(0);
							WTPartSubstituteLink ul = (WTPartSubstituteLink) obj.getObject();
							WTPartMaster wm = (WTPartMaster) ul.getRoleBObject();
							WTPart linkPart = BOMHelp.getPart(wm.getNumber(), "", childpart.getViewName());
							
							if(!map.containsKey(linkPart) && null != linkPart) {
								map.put(linkPart, part);
								map2.put(linkPart.getNumber(), part.getNumber());
							}
						}
					}
					map.put(childpart, part);
					map2.put(childpart.getNumber(), part.getNumber());
				}
				
				getChildPart(childpart, map, map2);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取物料的工艺文件、受控文件
	 * @param wtpart
	 * @author xucr
	 * @throws JSONException 
	 * @CreateDate 2020年10月13日
	 */
	private  JSONArray getWTPartFile(WTPart wtpart) throws JSONException {
		JSONArray array = new JSONArray();
		if(null != wtpart) {
			try {
				//说明文档：受控图纸、工艺文件都放在物料说明文档中
				QueryResult qr= WTPartHelper.service.getDescribedByWTDocuments(wtpart);
				WTDocument doc = null;
				String typeName = "";
				String url = "";
				JSONObject obj = null;
				while (qr.hasMoreElements()) {
					obj = new JSONObject();
					doc = (WTDocument) qr.nextElement();
					typeName = TypedUtility.getTypeIdentifier(doc).getTypename();
					
					if((typeName.contains(PROCESSDOCUMENTS) || typeName.contains(CONTROLDOCUMENT))
							&& "RELEASED".equals(doc.getState().getState().toString())) {
						
						url = getDocUrl(doc);
						
						obj.put("id", TMUtil.obj2Oid(doc));
						obj.put("name", doc.getName());
						obj.put("url", url);
						obj.put("effectiveTime", TMUtil.timestampToString(doc.getModifyTimestamp(),"yyyy-MM-dd"));
						
						array.put(obj);
					}
				}
			} catch (WTException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return array;
	}
	
	/**
	 * 查询文档链接
	 * @param doc
	 * @return
	 * @throws IOException
	 * @author xucr
	 * @CreateDate 2020年10月15日
	 */
	private  String getDocUrl(WTDocument doc) throws IOException {
		StringBuffer url = new StringBuffer();
		
		WTProperties pro = WTProperties.getLocalProperties();
		String localProperties = pro.getProperty("java.rmi.server.hostname");
		
		String pOid = TMUtil.obj2Oid(doc);
		
		url.append("http://").append(localProperties).append("/Windchill/app/#ptc1/tcomp/infoPage?oid=").append(pOid).append("&u8=1");
		
		return url.toString();
	}
}
